/**
 * app.js - Express应用配置
 * 
 * 这个文件配置Express应用程序，设置中间件，路由和错误处理。
 * 它是应用程序的核心，但不直接启动HTTP服务器（这是server.js的工作）。
 */

// 导入依赖
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const swaggerUi = require('swagger-ui-express');
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
const hpp = require('hpp');

// 导入自定义模块
const config = require('./config');
const logger = require('./utils/logger');
const swaggerSpec = require('./config/swagger');
const errorHandler = require('./middlewares/errorHandler');
const notFoundHandler = require('./middlewares/notFoundHandler');
const routes = require('./routes');

// 创建Express应用
const app = express();

// 设置信任代理，如果应用程序在代理后面运行
if (config.app.behindProxy) {
  app.set('trust proxy', 1);
}

// 请求日志记录
app.use(
  morgan(config.app.env === 'development' ? 'dev' : 'combined', {
    stream: {
      write: (message) => {
        logger.info(message.trim());
      },
    },
  })
);

// 安全中间件
app.use(helmet());

// 请求频率限制 (每个IP 100次/15分钟)
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100, // 每个IP限制100个请求
  message: '请求过于频繁，请稍后再试'
});
app.use(limiter);

// 防止NoSQL注入
app.use(mongoSanitize());

// 防止XSS攻击
app.use(xss());

// 防止HTTP参数污染
app.use(hpp());

// CORS配置
const corsOptions = {
  origin: function (origin, callback) {
    // 允许的域名列表
    const allowedOrigins = [
      'http://localhost:3000',
      'https://yourdomain.com'
    ];
    
    // 在生产环境中严格检查origin
    if (config.app.env === 'production') {
      if (!origin || allowedOrigins.indexOf(origin) !== -1) {
        callback(null, true);
      } else {
        callback(new Error('不允许的跨域请求'));
      }
    } else {
      // 开发环境允许所有来源
      callback(null, true);
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: ['Content-Length', 'X-Request-ID'],
  credentials: true,
  maxAge: 86400 // 24小时
};
app.use(cors(corsOptions));

// 压缩响应
app.use(compression());

// 解析JSON请求体 (限制为10kb)
app.use(express.json({ limit: '10kb' }));

// 解析URL编码的请求体 (限制为10kb)
app.use(express.urlencoded({ extended: true, limit: '10kb' }));

// 健康检查端点
app.get('/health', (req, res) => {
  res.status(200).json({
    status: 'success',
    message: '服务正在运行',
  });
});

// API文档
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));

// API路由
app.use(config.api.prefix, routes);

// 404处理程序
app.use(notFoundHandler.notFoundHandler);

// 错误处理中间件
app.use(errorHandler);

module.exports = app;